﻿Imports DotNetNuke
Imports DotNetNuke.Security
Imports DotNetNuke.Services.Localization
Imports DotNetNuke.Services.Exceptions
Imports DotNetNuke.Common
Imports System.Web.UI
Imports system.Text.RegularExpressions

Namespace effority.WF_HTML

    Partial Class HtmlModule
        Inherits WF_HTML_Base
        Implements DotNetNuke.Entities.Modules.IActionable

#Region " Private Methods "

        'Local tag cache to avoid multiple generations of the same tag
        Private tagCache As Hashtable

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' ManageUploadDirectory ensures that all image refs are to the correct directory
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Function ManageUploadDirectory(ByVal strHTML As String, ByVal strUploadDirectory As String) As String

            Dim P As Integer

            P = InStr(1, strHTML.ToLower, "src=""")
            While P <> 0
                ManageUploadDirectory = ManageUploadDirectory & Left(strHTML, P + 4)

                strHTML = Mid(strHTML, P + 5)

                ' add uploaddirectory if we are linking internally
                Dim strSRC As String = Left(strHTML, InStr(1, strHTML, """") - 1)
                If InStr(1, strSRC, "://") = 0 And Left(strSRC, 1) <> "/" And strSRC.IndexOf(strUploadDirectory.Substring(strUploadDirectory.IndexOf("Portals/"))) = -1 Then

                    strHTML = strUploadDirectory & strHTML
                End If

                P = InStr(1, strHTML.ToLower, "src=""")
            End While

            ManageUploadDirectory = ManageUploadDirectory & strHTML

        End Function

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Replaces all smart Tags in content with their appropriate values.
        ''' </summary>
        ''' <param name="content"></param>
        ''' <returns>Content with replaced Tags</returns>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------

        Private Function ProcessTags(ByVal content As String) As String
            Dim retval As New System.Text.StringBuilder

            Dim position As Integer = 0

            'Find all tags used in text
            'The regular expression matches the tag including the square brackets:
            'in "aaa[bbb[ccc]ddd]eee" it matches only "[ccc]"
            For Each _match As Match In Regex.Matches(content, "\[([^\[]*?)\]")
                'Append the text before the match to the result
                retval.Append(content.Substring(position, _match.Index - position))

                'Process the tag and append the output to the result
                retval.Append(ProcessTag(_match.Value))

                'Set the starting point for the next match
                position = _match.Index + _match.Value.Length

            Next

            'Append the rest of the text to the result
            retval.Append(content.Substring(position))

            Return retval.ToString
        End Function

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Processes all occurrences of the given tag by the given value in given content
        ''' </summary>
        ''' <param name="tag"></param>
        ''' <returns>Content with replaced Tag</returns>
        ''' <remarks>
        ''' A hashtable is used to make sure each tag will only be processed once each load.
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Function ProcessTag(ByVal tag As String) As String

            'Store the tag in the result to keep the text if its not a smarttag
            Dim retval As String = tag
            Dim tagitems As String() = tag.Substring(1, tag.Length - 2).Trim().Split(" ".ToCharArray())
            'Ensure case independency
            tagitems(0) = tagitems(0).ToUpper()
            'Initialize cache if not created
            If tagCache Is Nothing Then tagCache = New Hashtable
            'If we have tag in cache, simply return the cached content
            If tagCache.ContainsKey(tag) Then
                retval = tagCache(tag).ToString()
            Else
                'Build tag content value if its a known tag
                Select Case tagitems(0)
                    Case "PORTAL.NAME"
                        retval = PortalSettings.PortalName
                        tagCache(tag) = retval
                    Case "DATE"
                        If tagitems.Length = 2 Then
                            Try
                                retval = DateTime.Now.ToString(tagitems(1))
                            Catch
                                retval = DateTime.Now.ToShortDateString()
                            End Try
                        Else
                            retval = DateTime.Now.ToShortDateString()
                        End If
                        tagCache(tag) = retval
                    Case "TIME"
                        If tagitems.Length = 2 Then
                            Try
                                retval = DateTime.Now.ToString(tagitems(1))
                            Catch
                                retval = DateTime.Now.ToShortTimeString()
                            End Try
                        Else
                            retval = DateTime.Now.ToShortTimeString()
                        End If
                        tagCache(tag) = retval
                End Select
            End If

            Return retval
        End Function

        'effority Function
        Private Sub ProcessWF()

            pan_wf.Visible = False

            Dim cont As New effority.WF_HTML.HtmlTextController

            If cont.NewVersionAvaiable(ModuleId) And Me.UserLevel = UserLevelEnum.Workflow Then

                pan_wf.Visible = True

                hp_WF.NavigateUrl = EditUrl("WF_ControlCenter")

            End If

        End Sub

#End Region

#Region " Event Handlers "

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' Page_Load runs when the control is loaded
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

            Try

                If Not IsPostBack Then

                    effority.WF_HTML.HtmlTextController.InitPermissions()

                End If

                lblContent.EditEnabled = Me.IsEditable

                ' get HtmlText object
                Dim objHTML As New HtmlTextController
                Dim objText As HtmlTextInfo

                If Me.UserLevel = UserLevelEnum.Normal Then
                    objText = objHTML.GetHtmlTextActiveVersion(ModuleId)
                ElseIf Me.UserLevel = UserLevelEnum.Editor Or Me.UserLevel = UserLevelEnum.Workflow Then
                    objText = objHTML.GetHtmlTextLastVersion(ModuleId)
                End If

                Dim strContent As String

                ' get default content from resource file
                If Me.UserLevel = UserLevelEnum.Editor Or Me.UserLevel = UserLevelEnum.Workflow Then
                    strContent = Localization.GetString("AddContent", LocalResourceFile)
                End If

                ' get html
                If Not objText Is Nothing Then
                    strContent = Server.HtmlDecode(CType(objText.DeskTopHTML, String))
                    strContent = ProcessTags(strContent)

                    lblContent.Controls.Add(New LiteralControl(ManageUploadDirectory(strContent, PortalSettings.HomeDirectory)))
                Else
                    If Me.ShowEditorContent Then
                        lblContent.Controls.Add(New LiteralControl(ManageUploadDirectory(strContent, PortalSettings.HomeDirectory)))
                    End If
                End If

                Me.ProcessWF()

                ' menu action handler
                Dim ParentSkin As UI.Skins.Skin = UI.Skins.Skin.GetParentSkin(Me)
                'We should always have a ParentSkin, but need to make sure
                If Not ParentSkin Is Nothing Then
                    'Register our EventHandler as a listener on the ParentSkin so that it may tell us when a menu has been clicked.
                    ParentSkin.RegisterModuleActionEvent(Me.ModuleId, AddressOf ModuleAction_Click)
                End If


                Dim dateVisible As Boolean = Not Me.DisableDate

                If Settings(Consts.LAST_UPDATED_DATE) Is Nothing Then
                    dateVisible = False
                End If

                If dateVisible Then

                    Dim lastChanged As Date = New Date(CType(Settings(Consts.LAST_UPDATED_DATE), Long))

                    Dim str As String = Localization.GetString("lblLastChangeDate", Me.LocalResourceFile)

                    lblLastChangeDate.Text = String.Format(str, lastChanged.ToShortDateString)

                    lblLastChangeDate.Visible = True

                End If

            Catch exc As Exception

                ProcessModuleLoadException(Me, exc)

            End Try

        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' lblContent_UpdateLabel allows for inline editing of content
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Private Sub lblContent_UpdateLabel(ByVal source As Object, ByVal e As UI.WebControls.DNNLabelEditEventArgs) Handles lblContent.UpdateLabel

            ' get HtmlText object
            Dim objHTML As HtmlTextController = New HtmlTextController
            Dim objText As HtmlTextInfo = New HtmlTextInfo

            'If Me.UserLevel = UserLevelEnum.Normal Then
            '   objText = objHTML.GetHtmlTextActiveVersion(ModuleId)
            'ElseIf Me.UserLevel = UserLevelEnum.Editor Or Me.UserLevel = UserLevelEnum.Workflow Then
            '   objText = objHTML.GetHtmlTextLastVersion(ModuleId)
            'End If


            '' check if this is a new module instance
            'Dim blnIsNew As Boolean = False
            'If objText Is Nothing Then
            '   objText = New HtmlTextInfo
            '   blnIsNew = True
            'End If

            ' set content values
            objText.ModuleId = ModuleId
            objText.DeskTopHTML = e.Text
            objText.CreatedByUser = Me.UserId

            ' save the content
            objHTML.AddHtmlText(objText)


            ' refresh cache
            SynchronizeModule()

            Me.ProcessWF()

        End Sub

        ''' -----------------------------------------------------------------------------
        ''' <summary>
        ''' ModuleAction_Click handles all ModuleAction events raised from the skin
        ''' </summary>
        ''' <remarks>
        ''' </remarks>
        ''' <history>
        ''' </history>
        ''' -----------------------------------------------------------------------------
        Public Sub ModuleAction_Click(ByVal sender As Object, ByVal e As Entities.Modules.Actions.ActionEventArgs)

            If e.Action.Url.Length > 0 Then
                Response.Redirect(e.Action.Url, True)
            End If

        End Sub

#End Region

#Region " Optional Interfaces "

        Public ReadOnly Property ModuleActions() As Entities.Modules.Actions.ModuleActionCollection Implements Entities.Modules.IActionable.ModuleActions
            Get

                Dim Actions As New Entities.Modules.Actions.ModuleActionCollection

                Actions.Add(GetNextActionID, Localization.GetString(Entities.Modules.Actions.ModuleActionType.AddContent, LocalResourceFile), Entities.Modules.Actions.ModuleActionType.AddContent, "", "", EditUrl(), False, Security.SecurityAccessLevel.Edit, True, False)

                If Me.UserLevel = UserLevelEnum.Workflow Then
                    Actions.Add(GetNextActionID, Localization.GetString("WF_ControlCenter", LocalResourceFile), Entities.Modules.Actions.ModuleActionType.ModuleSettings, "", "", EditUrl("WF_ControlCenter"), False, Security.SecurityAccessLevel.View, True, False)
                End If

                Return Actions

            End Get
        End Property

#End Region

    End Class

End Namespace
